package com.song.utils;

import com.song.constants.AreaTypeEnum;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 *  省市县工具类
 *      第一位代表囯家\第二三位代表省份\第四位代表城市\最后两位代表区县
 */
public class AreaUtils {

    private static final Long AREA_CODE_COUNTRY_SCALE = 100000L;
    private static final Long AREA_CODE_PROVINCE_SCALE = 10000L;
    private static final Long AREA_CODE_CITY_SCALE = 100L;

    public static AreaTypeEnum getAreaLevelByAreaCode(Long areaCode) {
        if (StringUtils.isEmpty(areaCode)) {
            throw new RuntimeException("地区编码不能为空");
        } else if (!checkLength(areaCode)) {
            throw new RuntimeException("地区编码暂不支持");
        } else if (AREA_CODE_COUNTRY_SCALE.equals(areaCode)) {
            return AreaTypeEnum.COUNTRY;
        } else if (areaCode % AREA_CODE_PROVINCE_SCALE == 0L) {
            return AreaTypeEnum.PROVINCE;
        } else if (areaCode % AREA_CODE_CITY_SCALE == 0L) {
            return AreaTypeEnum.CITY;
        } else {
            return AreaTypeEnum.DISTRICT;
        }
    }

    public static Long getProvince(Long areaCode) {
        if (areaCode == null) {
            throw new RuntimeException("地区编码不能为空");
        } else if (!checkLength(areaCode)) {
            throw new RuntimeException("地区编码暂不支持");
        } else {
            return areaCode / AREA_CODE_PROVINCE_SCALE * AREA_CODE_PROVINCE_SCALE;
        }
    }

    public static Long getCity(Long areaCode) {
        if (areaCode == null) {
            throw new RuntimeException("地区编码不能为空");
        } else if (!checkLength(areaCode)) {
            throw new RuntimeException("地区编码暂不支持");
        } else {
            return areaCode / AREA_CODE_CITY_SCALE * AREA_CODE_CITY_SCALE;
        }
    }

    public static Long format(Long cityCode) {
        if (StringUtils.isEmpty(cityCode)) {
            return null;
        } else if (cityCode == 110000L) {
            return 110100L;
        } else if (cityCode == 120000L) {
            return 120100L;
        } else if (cityCode == 130000L) {
            return 130100L;
        } else {
            return cityCode;
        }
    }

    public static boolean isCountry(Long areaCode) {
        AreaTypeEnum areaLevel = getAreaLevelByAreaCode(areaCode);
        return areaLevel == AreaTypeEnum.COUNTRY;
    }

    public static boolean isProvince(Long areaCode) {
        AreaTypeEnum areaLevel = getAreaLevelByAreaCode(areaCode);
        return areaLevel == AreaTypeEnum.PROVINCE;
    }

    public static boolean isCity(Long areaCode) {
        AreaTypeEnum areaLevel = getAreaLevelByAreaCode(areaCode);
        return areaLevel == AreaTypeEnum.CITY;
    }

    public static boolean isDistrict(Long areaCode) {
        AreaTypeEnum areaLevel = getAreaLevelByAreaCode(areaCode);
        return areaLevel == AreaTypeEnum.DISTRICT;
    }

    public static boolean checkLength(Long areaCode) {
        if (areaCode == null) {
            return false;
        }
        return areaCode / AREA_CODE_COUNTRY_SCALE < 10L && areaCode / AREA_CODE_COUNTRY_SCALE > 0L;
    }


    public static boolean isChildren(Long areaCode, Long subAreaCode) {
        // 不为空
        if (null != areaCode && null != subAreaCode) {
            //区域编码不是国家，且编码不相等
            if (!AREA_CODE_COUNTRY_SCALE.equals(areaCode) && !subAreaCode.equals( areaCode)) {
                // 如果 判断值 除以城市编码/100L * 100L 等于区域编码
                if (subAreaCode / AREA_CODE_CITY_SCALE * AREA_CODE_CITY_SCALE == areaCode) {
                    return true;
                    // 如果 判断值 除以省编码/10000L * 10000L 等于区域编码
                } else if (subAreaCode / AREA_CODE_PROVINCE_SCALE * AREA_CODE_PROVINCE_SCALE == areaCode) {
                    System.out.println("areaCode=>"+areaCode+":subAreaCode=>"+subAreaCode);
                    System.out.println("subAreaCode / AREA_CODE_PROVINCE_SCALE=>"+subAreaCode / AREA_CODE_PROVINCE_SCALE);
                    System.out.println("subAreaCode / AREA_CODE_PROVINCE_SCALE * AREA_CODE_PROVINCE_SCALE=>"+subAreaCode / AREA_CODE_PROVINCE_SCALE * AREA_CODE_PROVINCE_SCALE);
                    System.out.println("subAreaCode / AREA_CODE_PROVINCE_SCALE * AREA_CODE_PROVINCE_SCALE == areaCode=>"+(subAreaCode / AREA_CODE_PROVINCE_SCALE * AREA_CODE_PROVINCE_SCALE == areaCode));
                    return true;
                } else {
                    // 否则
                    return subAreaCode > 999999L && isChildren(areaCode, subAreaCode / 1000L);
                }
            } else {
                return true;
            }
        } else {
            return false;
        }
    }

    public static List<Long> filterChildren(List<Long> areaCodeList, Long areaCode) {
        return areaCodeList.stream().filter(children -> isChildren(areaCode, children)).collect(Collectors.toList());
    }
}
